/******************************************************
*  Copyright(c) pages.ilovezxl.top
*  FileName : cli.c
*  Author : rivulet.dave
*  Description : 文件系统接口
*  Data : 2020-07-20
******************************************************/

/*********************************************************************
 * INCLUDES
 */

#include "stdrope.h"
#include "sallib.h"
#include "salagent.h"


#if (SAL_FS == _ENABLE)

#include "fs.h"

#if (SAL_FS_PRODUCER == _FS_LINUX_)
#include "fs_linux.h"
#elif (SAL_FS_PRODUCER == _FS_FAT32_)
#include "fs_fat32.h"
#else
#error "fs producer no define."
#endif

/*********************************************************************
 *  EXTERNAL VARIABLES
 */

/*********************************************************************
 * MACROS
 */

/*********************************************************************
 * TYPES
 */

/*********************************************************************
 * FUNCTIONS DECLARE
 */


/*********************************************************************
 *  VARIABLES
 */

static FS_BASE_S *s_pstFSBaseObject = NULL;

/*********************************************************************
 * FUNCTIONS
 */

/**
 *   @Description: 文件系统初始化
 *   @param: NA
 *   @return :FRESULT_E
 */
FRESULT_E fsInstall(void)
{
#if (SAL_FS_PRODUCER == _FS_LINUX_)
    s_pstFSBaseObject = fsLinuxObjNew();
#elif (SAL_FS_PRODUCER == _FS_FAT32_)
    s_pstFSBaseObject = fsFat32ObjNew();
#else
#endif
    return FS_OK;
}

/**
 *   @Description: 文件系统逆初始化
 *   @param: pName - 入参，任务名称
 *   @return :FRESULT_E
 */
FRESULT_E fsUninstall(void)
{
#if (SAL_FS_PRODUCER == _FS_LINUX_)
    fsLinuxObjDelete();
#elif (SAL_FS_PRODUCER == _FS_FAT32_)
    fsFat32ObjDelete();
#else
#endif
    s_pstFSBaseObject = NULL;
    return FS_OK;
}

/**
 *   @Description: 打开或创建文件
 *   @param: phFile - 出参，文件描述符
 *   @param: pcPath - 入参，文件路径
 *   @param: ucMode - 入参，文件操作模式
 *   @return :FRESULT_E
 */
FRESULT_E fsOpen(fd_t *phFile, const char* pcPath, uint8_t ucMode)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSOpen)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSOpen(phFile, pcPath, ucMode);
}

/**
 *   @Description: 关闭文件
 *   @param: phFile - 入参，文件描述符
 *   @return :FRESULT_E
 */
FRESULT_E fsClose(fd_t *phFile)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSClose(phFile))
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSClose(phFile);
}

/**
 *   @Description: 读取文件内容
 *   @param: phFile - 入参，文件描述符
 *   @param: pBuff - 入参，缓存地址
 *   @param: uiSize - 入参，读取数据大小
 *   @return :FRESULT_E/实际读取到的数据大小
 */
int32_t fsRead(fd_t *phFile, void *pBuff, uint32_t uiSize)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSRead)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSRead(phFile, pBuff, uiSize);
}

/**
 *   @Description: 读取文件一行
 *   @param: phFile - 入参，文件描述符
 *   @param: pBuff - 入参，缓存地址
 *   @param: uiSize - 入参，读取数据大小
 *   @return :FRESULT_E/实际读取到的数据大小
 */
int32_t fsReadLine(fd_t *phFile, void *pBuff, uint32_t uiSize)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSReadLine)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSReadLine(phFile, pBuff, uiSize);
}

/**
 *   @Description: 向文件写入数据
 *   @param: phFile - 入参，文件描述符
 *   @param: pBuff - 入参，缓存地址
 *   @param: uiSize - 入参，写入的数据大小
 *   @return :FRESULT_E/实际写入的数据大小
 */
int32_t fsWrite(fd_t *phFile, const void *pBuff, uint32_t uiSize)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSWrite)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSWrite(phFile, pBuff, uiSize);
}

/**
 *   @Description: 重置/定位文件操作偏移指针
 *   @param: phFile - 入参，文件描述符
 *   @param: iOffset - 入参，相对于基准点的偏移距离(单位:字节)  ( 正数:向后偏移  负数:向前偏移)
 *   @param: ucWhence - 入参，文件偏移指针位置设置的基准点 SEEK_POS_E
 *   @return :FRESULT_E
 */
FRESULT_E fsSeek(fd_t *phFile, int32_t iOffset, uint8_t ucWhence)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSSeek)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSSeek(phFile, iOffset, ucWhence);
}

/**
 *   @Description: 删除文件
 *   @param: pName - 入参，文件名
 *   @return :FRESULT_E
 */
FRESULT_E fsDelete(const char *pName)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSDelete)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSDelete(pName);
}

/**
 *   @Description: 获取文件大小
 *   @param: phFile - 入参，文件描述符
 *   @param: puiSize - 出参，文件大小
 *   @return :FRESULT_E
 */
FRESULT_E fsGetSize(fd_t *phFile, uint32_t *puiSize)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSGetSize)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSGetSize(phFile, puiSize);
}

/**
 *   @Description: 将缓存的数据写入到文件中
 *   @param: phFile - 入参，文件描述符
 *   @return :FRESULT_E
 */
FRESULT_E fsFlush(fd_t *phFile)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSFlush)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSFlush(phFile);
}

/**
 *   @Description: 文件重命名
 *   @param: pOldPathle - 入参，原文件名
 *   @param: pNewPath - 入参，新文件名
 *   @return :FRESULT_E
 */
FRESULT_E fsRename(const char *pOldPath, const char *pNewPath)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSRename)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSRename(pOldPath, pNewPath);
}

/**
 *   @Description: 创建目录
 *   @param: pPath - 入参，路径
 *   @return :FRESULT_E
 */
FRESULT_E fsMkDir(const char *pPath)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSMkDir)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSMkDir(pPath);
}

/**
 *   @Description: 打开目录文件
 *   @param: pcDirPath - 入参，目录路径
 *   @param: pstDir - 出参，目录信息
 *   @return FRESULT_E
 */
FRESULT_E fsDirOpen(const char *pcDirPath, FSDIR_S *pstDir)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSDirOpen)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSDirOpen(pcDirPath, pstDir);
}

/**
 *   @Description: 关闭目录
 *   @param: pstDir - 入参，目录句柄
 *   @return :FRESULT_E
 */
FRESULT_E fsDirClose(FSDIR_S *pstDir)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSDirClose)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSDirClose(pstDir);
}

/**
 *   @Description: 读取指定目录下的文件信息，遍历目录下的所有文件
 *   @param: pstDir - 入参，目录句柄
 *   @param: pstFileInfo - 出参，读出的文件信息
 *   @return :FRESULT_E
 */
FRESULT_E fsDirRead(FSDIR_S *pstDir, FILE_INFO_S *pstFileInfo)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSDirRead)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSDirRead(pstDir, pstFileInfo);
}

/**
 *   @Description: 获取当前目录
 *   @param: pBuf - 出参，保存当前目录的缓冲区
 *   @param: uiSize - 入参，缓冲区大小
 *   @return :成功返回指向当前目录的指针，和buf 的值一样，错误返回NULL
 */
char *fsGetCwd(char *pBuf, uint32_t uiSize)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSGetCwd)
    {
        return NULL;
    }
    return s_pstFSBaseObject->pfFSGetCwd(pBuf, uiSize);
}

/**
 *   @Description: 改变当前工作目录
 *   @param: pPath - 入参，工作目录路径
 *   @return :FRESULT_E
 */
FRESULT_E fsChDir(const char *pPath)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSChDir)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSChDir(pPath);
}

/**
 *   @Description: 文件或目录是存在
 *   @param: pPath - 入参，路径
 *   @return :FRESULT_E, FS_OK表示存在
 */
FRESULT_E fsIsExist(const char *pPath)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSIsExist)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSIsExist(pPath);
}

/**
 *   @Description: 更改文件属性
 *   @param: pPath - 入参，文件路径
 *   @param: uiMode - 入参，文件属性
 *   @return :FRESULT_E
 */
FRESULT_E fsChMod(const char *pPath, uint32_t uiMode)
{
    if (!s_pstFSBaseObject || !s_pstFSBaseObject->pfFSChMod)
    {
        return FS_INT_ERR;
    }
    return s_pstFSBaseObject->pfFSChMod(pPath, uiMode);
}

#endif  // SAL_FS == _ENABLE

/************************************** The End Of File **************************************/

